﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using DapperLambdaSQL.Model.Exceptions;

namespace DapperLambdaSQL.Utils
{
    /// <summary>
    /// 解析表达式
    /// </summary>
    public static class ParseExpression
    {
        /// <summary>
        /// 解析 表达式
        /// </summary>
        /// <typeparam name="T">被解析类型</typeparam>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns>成员名称</returns>
        public static IEnumerable<string> Parse<T, TElement>(Expression<Func<T, TElement>> expression)
        {
            if (expression == null) return null;

            return expression.Body switch
            {
                NewExpression nbody => ParseNewExpression(nbody),
                LambdaExpression lbody => new string[] { ParseLambdaExpression(lbody) },
                MemberExpression mbody => new string[] { ParseMemberExpression(mbody) },
                UnaryExpression ubody => new string[] { ParseUnaryExpression(ubody) },
                _ => throw new ParseExpressionException(expression),
            };
        }

        /// <summary>
        /// 解析 NewExpression 表达式
        /// </summary>
        /// <param name="body">被解析主体</param>
        /// <returns>成员名称</returns>
        public static IEnumerable<string> ParseNewExpression(NewExpression body)
        {
            var fileds = new List<string>();
            foreach (var item in body.Members)
            {
                fileds.Add(item.Name);
            }

            return fileds;
        }

        /// <summary>
        /// 解析 LambdaExpression 表达式
        /// </summary>
        /// <param name="body">被解析主体</param>
        /// <returns></returns>
        public static string ParseLambdaExpression(LambdaExpression body)
        {
            return "";
        }

        /// <summary>
        /// 解析 MemberExpression 表达式
        /// </summary>
        /// <param name="body">被解析主体</param>
        /// <returns>成员名称</returns>
        public static string ParseMemberExpression(MemberExpression body)
        {
            return body.Member.Name;
        }

        /// <summary>
        /// 解析 UnaryExpression 表达式
        /// </summary>
        /// <param name="body">被解析主体</param>
        /// <returns>成员名称</returns>
        public static string ParseUnaryExpression(UnaryExpression body)
        {
            var memberExpression = body.Operand as MemberExpression;
            return memberExpression.Member.Name;
        }
    }
}